#pragma once

#ifndef VTTATLAS_H
#define VTTATLAS_H

#include "VTTObject.h"
#include "VTTConfiguration.h"

#include <map>
#include <string>
#include <vector>

#include <boost/thread/thread.hpp>

class VTTImage;
class VTTPackNode;

/**
  *	VTTAtlas objects represent Virtual Texture Atlases. They can be configured
  * with configuration objects and can then be written to disc.
  */
class VTTAtlas : public VTTObject
{

public:
	VTTAtlas( const VTTConfiguration &vttConfig );
	VTTAtlas( const VTTAtlas &atlas );
	~VTTAtlas( void );

	const VTTConfiguration &GetConfiguration( void ) const;
	const std::string &GetFullPath( void ) const;
	const std::map<std::string, VTTImage*> &GetNamesToImagesMap( void ) const;
	UINT32 GetPartsPerSide( void ) const;
	UINT32 GetPartSideLength( void ) const;
	UINT32 GetSideLength( void ) const;
	bool GetWriteResult( void ) const;

	bool Init( const VTTConfiguration &vttConfig );
	bool IsWriting( void ) const;

	bool ReloadImage( const std::string &imageName );

	void Write( bool overwrite = true, void (*callbackFunction)(bool) = 0 );
	void WriteInSeparateThread( bool overwrite = true, void (*callbackFunction)(bool) = 0 );

	bool WriteOffsetFile( void ) const;

private:
	/** Configuration that is needed during the Atlas generation process. The configuration provides information like the border, tileSize etc. */
	VTTConfiguration mConfiguration;
	/** Pack Node that represents the whole area of the Atlas. The images of the Atlas are inserted into the tree of which this pack node is the root */
	VTTPackNode *mRootPackNode;

	/** Grey value [0..255] that is used for the empty areas in the Atlas */
	unsigned char mEmptyAreaGreyValue;

	/** Map, that maps names (not paths!) of images to the corresponding image objects */
	std::map<std::string, VTTImage*> mNamesToImagesMap;
	/** All the names of the images that are part of the Atlas*/
	std::vector<std::string> mImageNames;
	/** All the image objects that are part of the Atlas*/
	std::vector<VTTImage*> mImages;
	/** Boolean value indicating whether the Atlas is currently generated or not */
	bool mIsWriting;
	/** Result of the last Atlas generation process. Boolean value that is true when the generation was successful, otherwise false */
	bool mWriteResult;

	/** Thread that is used for the Atlas generation process */
	boost::thread mWriteThread;

	/** Number of Atlas parts per side, always a number that is power of two: 2, 4, 8 etc. */
	UINT32 mPartsPerSide;
	/** Side length of a single Atlas part in pixels */
	UINT32 mPartSideLength;
	/** Side length of the whole Atlas in pixels */
	UINT32 mSideLength;
	/** Number of components in a single pixel of the Atlas */
	UINT32 mNumComponents;

	/** Full directory path of the Atlas */
	std::string mFullPath;

	void Reset( void );

	static void WriteThread( VTTAtlas *atlas, bool overwrite = true, void (*callbackFunction)(bool) = 0 );
};

#endif